package com.guozcc.gateway.routes;

import com.guozcc.gateway.autofilter.autogatewayfilter.*;
import com.guozcc.gateway.autofilter.base.BodyRewriteImpl;
import com.guozcc.gateway.autopredicates.AutoHeaderRoutePredicateFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

@Configuration
public class RouteDefinitionConfig {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AutoGatewayAfterOneFilter autoGatewayAfterOneFilter;
    @Autowired
    private AutoGatewayAfterZeroFilter autoGatewayAfterZeroFilter;
    @Autowired
    private AutoGatewayBeforeZeroFilter autoGatewayBeforeZeroFilter;
    @Autowired
    private AutoGatewayZeroFilter autoGatewayZeroFilter;
    @Autowired
    private AutoHeaderRoutePredicateFactory autoHeaderRoutePredicateFactory;
    @Autowired
    private SentinelGatewayFilter sentinelGatewayFilter;

    @Bean
    public RouteLocator getRouteDefinition(RouteLocatorBuilder builder){
        return builder.routes()
                /**
                 * 类类型路由配置举例以及过滤器执行顺序演示Demo
                 */
                .route("ID1",r -> r
                        /*
                         *断言集合
                         */
                        .path("/testRouteDemo/**")
                        .or()
                        .path("/testRouteDemo1/**")
                        .and()
                        .header("token")
                        .and()
                        .predicate(autoHeaderRoutePredicateFactory.apply(new AutoHeaderRoutePredicateFactory.Config("aaa","bbb")))//自定义断言

                        /*
                         * 过滤器执行顺序的问题
                         *    Order值越小，过滤器越早生效，前置执行逻辑靠前执行，后置逻辑靠后执行
                         *      PS:
                         *      局部过滤器前置执行order=-1： AutoGatewayBeforeZeroFilter
                         *      全局过滤器前置执行order= 0： AutoGlobalFilter
                         *      局部过滤器前置执行order= 0： AutoGatewayZeroFilter
                         *      局部过滤器前置执行order= 1： AutoGatewayAfterZeroFilter
                         *      局部过滤器后置执行order= 1： AutoGatewayAfterZeroFilter
                         *      局部过滤器后置执行order= 0： AutoGatewayZeroFilter
                         *      全局过滤器前置执行order= 0： AutoGlobalFilter
                         *      局部过滤器后置执行order=-1： AutoGatewayBeforeZeroFilter
                         */
                        .filters(f -> f
                                .filter(autoGatewayBeforeZeroFilter) //自定义过滤器
                                .filter(autoGatewayZeroFilter) //自定义过滤器
                                .filter(autoGatewayAfterZeroFilter) //自定义过滤器
                                .stripPrefix(100) //内置过滤器：截取路径过滤器
                        )

                        /**
                         * 下游域名
                         */
                        .uri("http://gitee.com")
                )
                /**
                 * 对请求报文以及响应报文进行操作演示demo
                 */
                .route("ID2",r -> r
                                .path("/testModifyRequestBody")
                                .filters(f -> f
                                        .modifyRequestBody(byte[].class,byte[].class,new BodyRewriteImpl())//操作请求体内容
                                        .modifyResponseBody(byte[].class,byte[].class,new BodyRewriteImpl())//操作响应体内容
                                )
                                .uri("http://zhuanlan.zhihu.com"))
                .route("ID3",r -> r
                                .path("/ID3/demo/demo000**")
                                .filters(f -> f
                                        //匿名内部类实现操作请求体内容,body为空则不触发
                                        .modifyRequestBody(byte[].class,byte[].class, (serverWebExchange, bytes) -> {
                                            try {
                                                String msg = new String(bytes, "UTF-8");
                                                log.info("请求报文："+msg);
                                                serverWebExchange.getAttributes().put("msg_request",msg);
                                            }catch (Exception e){
                                                log.error("",e);
                                            }
                                            //return Mono.just(new JSONObject().fluentPut("dlrs",100).toJSONString().getBytes());
                                            return Mono.just(bytes);

                                        })
                                        //匿名内部类实现操作响应体内容
                                        .modifyResponseBody(byte[].class,byte[].class,(serverWebExchange, bytes) -> {
                                            try {
                                                String msg = new String(bytes, "UTF-8");
                                                log.info("响应报文："+msg);
                                                serverWebExchange.getAttributes().put("msg_response",msg);
                                            }catch (Exception e){
                                                log.error("",e);
                                            }
                                            return Mono.just(bytes);
                                        })
                                        .stripPrefix(1)
                                        .filter(sentinelGatewayFilter)
                                        .filter(autoGatewayAfterOneFilter)
                                        .addRequestHeader("Content-Type","application/json")
                                )
                                .uri("http://127.0.0.1:8081"))
                .build();
    }
}
